﻿using Firefly.Framework.ContentManagement;
using Firefly.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Firefly.Framework.Components.Water
{
    public class WaterShader : ShaderProxy, IShaderProxy
    {
        public Vector3 SunlightDirection
        {
            get { return Effect.Parameters["SunlightDirection"].GetValueVector3(); }
            set { Effect.Parameters["SunlightDirection"].SetValue(value); }
        }
        public Vector4 SunlightColor
        {
            get { return Effect.Parameters["SunlightColor"].GetValueVector4(); }
            set { Effect.Parameters["SunlightColor"].SetValue(value); }
        }
        public Vector3 CameraPosition
        {
            get { return Effect.Parameters["CameraPosition"].GetValueVector3(); }
            set { Effect.Parameters["CameraPosition"].SetValue(value); }
        }
        public Vector2 WaveMapOffset0
        {
            get { return Effect.Parameters["WaveMapOffset0"].GetValueVector2(); }
            set { Effect.Parameters["WaveMapOffset0"].SetValue(value); }
        }
        public Vector2 WaveMapOffset1
        {
            get { return Effect.Parameters["WaveMapOffset1"].GetValueVector2(); }
            set { Effect.Parameters["WaveMapOffset1"].SetValue(value); }
        }
        public Texture2D WaveMap0
        {
            get { return Effect.Parameters["WaveMap0"].GetValueTexture2D(); }
            set { Effect.Parameters["WaveMap0"].SetValue(value); }
        }
        public Texture2D WaveMap1
        {
            get { return Effect.Parameters["WaveMap1"].GetValueTexture2D(); }
            set { Effect.Parameters["WaveMap1"].SetValue(value); }
        }
        public Texture2D RefractionMap
        {
            get { return Effect.Parameters["RefractionMap"].GetValueTexture2D(); }
            set { Effect.Parameters["RefractionMap"].SetValue(value); }
        }
        public Texture2D ReflectionMap
        {
            get { return Effect.Parameters["ReflectionMap"].GetValueTexture2D(); }
            set { Effect.Parameters["ReflectionMap"].SetValue(value); }
        }

        public WaterShader(IQuadWater parent)
            : base(parent)
        {
            EffectName = "Effects\\Water\\Water1";
        }

        #region IShaderProxy Members

        public override Matrix View { get; set; }
        public override Matrix Projection { get; set; }

        public override void Draw(GameTime gameTime)
        {
            QuadWater t = Parent as QuadWater;
            Effect.Begin();
            Effect.Parameters["WorldViewProjection"].SetValue(World * (View * Projection));
            //Time = (float)gameTime.TotalRealTime.TotalSeconds;
            
            foreach (EffectPass pass in Effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                t.VertexMap.DrawIndexedPrimitives();
                pass.End();
            }

            Effect.End();
        }

        #endregion

        #region IHasContent Members

        public override void LoadContent()
        {
            Effect = ContentService.Instance.Load<Effect>(EffectName);
            Effect.CurrentTechnique = Effect.Techniques["Render"];
            World = Matrix.Identity;
            SunlightDirection = Vector3.Normalize(new Vector3(.5f, .5f, .8f));
            SunlightColor = new Vector4(2.3f, 2f, 1.8f, 1.0f);
            //SunlightPower = 25f;
            //SunlightFactor = 10.5f;
            //WaveMapScale = 1.5f;
            //WaterColor = new Vector4(0.475f, 0.675f, 0.70625f, 1.0f);
            WaveMap0 = ContentService.Instance.Load<Texture2D>("Textures\\Water\\WaveMap0");
            WaveMap1 = ContentService.Instance.Load<Texture2D>("Textures\\Water\\WaveMap1");
        }

        public override void UnloadContent()
        {
            ContentService.Instance.Release(EffectName);
        }

        #endregion

        #region IDisposable Members

        ~WaterShader()
        {
            Dispose(false);
        }

        #endregion
    }
}
